#include "beamquality3d.h"
#include "ui_beamquality3d.h"
#include <QtDebug>
#include <QFormLayout>
#include <QMessageBox>
#include <QFileDialog>
beamquality3d::beamquality3d(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::beamquality3d),
    m_zValue(0.0f),
    m_majorAxis(30.0f),
    m_minorAxis(20.0f),
    m_ellipseAngle(0.0f),
    m_surface(nullptr),
    m_ellipseCount(0),
    m_selectedEllipseId(-1)  // 初始化为-1，表示没有选中的椭圆
{
    ui->setupUi(this);
    this->setWindowTitle("椭圆曲面图");
    m_surface = create3DSurfaceGraph(m_zValue, m_majorAxis, m_minorAxis, m_ellipseAngle);
    setupEllipseControls();
    if (m_ellipseGroupBox) {
        m_ellipseGroupBox->setVisible(true);
    }
    // 初始化删除按钮状态
    m_removeButton->setEnabled(false);
}

beamquality3d::~beamquality3d()
{
    if (m_surface) {
        delete m_surface;
        m_surface = nullptr;
    }
    delete ui;
}


Q3DSurface *beamquality3d::create3DSurfaceGraph(float z, float major, float minor, float angle)
{
    // 初始化3D图形界面
    initialize3DSurfaceGraph();

    // 添加椭圆（使用默认颜色）
    addEllipseTo3DSurface(z, major, minor, angle, QColor(0, 128, 255));

    return m_surface;
}

QValue3DAxis *beamquality3d::createValue3DAxis(QString axisTitle, bool titleVisible, float min, float max)
{
    // 创建值坐标轴对象
    QValue3DAxis *axis = new QValue3DAxis;
    axis->setTitle(axisTitle);  // 设置坐标轴标题
    axis->setTitleVisible(titleVisible); // 设置标题是否显示
    axis->setRange(min, max);   // 设置坐标轴取值范围



    // 设置标签格式，确保0点标签显示
    axis->setLabelFormat("%.1f");

    // 设置分段数量，使网格线更密集，更容易看到0点
    axis->setSegmentCount(10);

    // 返回坐标轴对象
    return axis;
}

void beamquality3d::on_angleValueChange(int val)
{
    // 拿到信号发送者
    QSpinBox *spinBox = dynamic_cast<QSpinBox *>(sender());

    // 若当前为定时改变视角则不设置活动摄像角度，并将动态属性值设置为false
    if(spinBox->property("RotationFlag").toBool())
    {
        spinBox->setProperty("RotationFlag", false);
        return;
    }

    // 拿到视角类型
    int type = spinBox->property("DirectionType").toInt();

    if (m_surface) {
        // 判断当前方向类型，并将角度赋到对应位置
        if(0 == type)
        {
            // 设置曲面图的X轴视角
            m_surface->scene()->activeCamera()->setXRotation(val);
        }
        else if(1 == type)
        {
            // 设置曲面图的Y轴视角
            m_surface->scene()->activeCamera()->setYRotation(val);
        }
    }
}

void beamquality3d::timerEvent(QTimerEvent *event)
{
    Q_UNUSED(event);

    if (m_surface) {
        // 获取当前摄像头对象
        Q3DCamera *curCamera = m_surface->scene()->activeCamera();

        // 获取当前视角值
        int curCameraPreset = curCamera->cameraPreset();
        // 判断获取下一是视角值
        int cameraPreset = curCameraPreset == 21? 1: curCameraPreset + 1;
        // 设置相机视角
        curCamera->setCameraPreset(Q3DCamera::CameraPreset(cameraPreset));

        // 设置水平视角控件值
        ui->horAngleSpinBox->setValue(curCamera->xRotation());
        // 设置水平动态属性
        ui->horAngleSpinBox->setProperty("RotationFlag", true);
        // 设置垂直视角控件值
        ui->verAngleSpinBox->setValue(curCamera->yRotation());
        // 设置水平动态属性
        ui->verAngleSpinBox->setProperty("RotationFlag", true);
    }
}


void beamquality3d::on_themeComboBox_currentIndexChanged(int index)
{
    if (m_surface) {
        // 设置曲面图主题
        m_surface->activeTheme()->setType(Q3DTheme::Theme(index));
    }
}


void beamquality3d::on_scaleSlider_sliderMoved(int position)
{
    if (m_surface) {
        // 设置曲面图缩放
        m_surface->scene()->activeCamera()->setZoomLevel(position);
    }
}

void beamquality3d::on_autoSwitchAngleBtn_clicked(bool checked)
{
    // 根据状态做出相应操作
    if(checked)
    {
        // 改变按钮文本
        ui->autoSwitchAngleBtn->setText("停止");
        // 启动定时器
        m_timer = startTimer(750);
    }
    else
    {
        // 改变按钮文本
        ui->autoSwitchAngleBtn->setText("开始");
        // 终止定时器
        killTimer(m_timer);
    }
}


void beamquality3d::setupEllipseControls()
{
    // 创建椭圆参数分组框
    m_ellipseGroupBox = new QGroupBox("椭圆参数", this);

    // 创建布局
    QFormLayout *layout = new QFormLayout(m_ellipseGroupBox);

    // 创建Z值输入框
    m_zValueSpinBox = new QDoubleSpinBox(m_ellipseGroupBox);
    m_zValueSpinBox->setRange(-100.0, 100.0);
    m_zValueSpinBox->setValue(m_zValue);
    m_zValueSpinBox->setSingleStep(1.0);
    layout->addRow("Z值:", m_zValueSpinBox);

    // 创建主轴长度输入框
    m_majorSpinBox = new QDoubleSpinBox(m_ellipseGroupBox);
    m_majorSpinBox->setRange(1.0, 100.0);
    m_majorSpinBox->setValue(m_majorAxis);
    m_majorSpinBox->setSingleStep(1.0);
    layout->addRow("主轴长度:", m_majorSpinBox);

    // 创建次轴长度输入框
    m_minorSpinBox = new QDoubleSpinBox(m_ellipseGroupBox);
    m_minorSpinBox->setRange(1.0, 100.0);
    m_minorSpinBox->setValue(m_minorAxis);
    m_minorSpinBox->setSingleStep(1.0);
    layout->addRow("次轴长度:", m_minorSpinBox);

    // 创建角度输入框
    m_angleSpinBox = new QDoubleSpinBox(m_ellipseGroupBox);
    m_angleSpinBox->setRange(0.0, 360.0);
    m_angleSpinBox->setValue(m_ellipseAngle);
    m_angleSpinBox->setSingleStep(5.0);
    layout->addRow("角度(°):", m_angleSpinBox);

    // 创建添加椭圆按钮
    QPushButton *addEllipseButton = new QPushButton("添加新椭圆", m_ellipseGroupBox);
    layout->addRow(addEllipseButton);

    // 创建清除所有椭圆按钮
    QPushButton *clearButton = new QPushButton("清除所有椭圆", m_ellipseGroupBox);
    layout->addRow(clearButton);

    // 创建删除选中椭圆按钮
    m_removeButton = new QPushButton("删除选中椭圆", m_ellipseGroupBox);
    layout->addRow(m_removeButton);

    // 创建加载图像按钮
    QPushButton *loadImageButton = new QPushButton("加载图像", m_ellipseGroupBox);
    layout->addRow(loadImageButton);

    // 连接信号和槽
    connect(addEllipseButton, &QPushButton::clicked, this, &beamquality3d::on_addEllipseButton_clicked);
    connect(clearButton, &QPushButton::clicked, this, &beamquality3d::on_clearButton_clicked);
    connect(m_removeButton, &QPushButton::clicked, this, &beamquality3d::on_removeButton_clicked);
    connect(loadImageButton, &QPushButton::clicked, this, &beamquality3d::onLoadImageClicked);

    // 将分组框添加到界面中
    ui->verticalLayout_2->addWidget(m_ellipseGroupBox);

}


Q3DSurface* beamquality3d::initialize3DSurfaceGraph()
{
    if (m_surface) {
        return m_surface;
    }

    m_surface = new Q3DSurface;
    QWidget *container = QWidget::createWindowContainer(m_surface);
    ui->stackedWidget->addWidget(container);

    m_surface->setAxisX(createValue3DAxis("X Axis", true, -10, 10));
    m_surface->setAxisY(createValue3DAxis("Y Axis", true, -10, 10));
    m_surface->setAxisZ(createValue3DAxis("Z Axis", true, 0, 20));
    m_surface->activeTheme()->setType(Q3DTheme::ThemeQt);
    m_surface->setShadowQuality(QAbstract3DGraph::ShadowQualityMedium);
    m_surface->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
    return m_surface;
}

void beamquality3d::addEllipseTo3DSurface(float z, float major, float minor, float angle, const QColor &color)
{

    Q3DSurface *surface = initialize3DSurfaceGraph();
    const float angleRad = angle * M_PI / 180.0f;
    const float sinTheta = sin(angleRad);
    const float cosTheta = cos(angleRad);
    float yMax = minor * sinTheta;
    float zMax = z * (1 + cosTheta);
    QValue3DAxis *axisX = surface->axisX();
    QValue3DAxis *axisY = surface->axisY();
    QValue3DAxis *axisZ = surface->axisZ();
    axisX->setRange(qMin(axisX->min(), -major), qMax(axisX->max(), major));
    axisY->setRange(qMin(axisY->min(), -yMax), qMax(axisY->max(), yMax));
    axisZ->setRange(qMin(axisZ->min(), 0.0f), qMax(axisZ->max(), zMax * 1.5f));
    QSurface3DSeries *series = new QSurface3DSeries;
    series->setDrawMode(QSurface3DSeries::DrawSurfaceAndWireframe);
    series->setFlatShadingEnabled(false);
    series->setBaseColor(color);  // 设置颜色
    series->setName(QString("Ellipse_%1").arg(++m_ellipseCount));

    QSurfaceDataArray *array = new QSurfaceDataArray;

    const int rows = 50;    // 行数
    const int cols = 50;    // 列数
    for (int i = 0; i < rows; ++i) {
        QSurfaceDataRow *dataRow = new QSurfaceDataRow;
        float t = 2.0f * M_PI * i / (rows - 1); // 参数t从0到2π

        for (int j = 0; j < cols; ++j) {
            float r = j / static_cast<float>(cols - 1); // 半径比例从0到1

            float a = r * major * cos(t); // x坐标
            float b = r * minor * sin(t); // y坐标
            float c = z; // z坐标
            float newX = a;
            float newY = b * sinTheta;
            float newZ = c+b*cosTheta;
            dataRow->append(QVector3D(newX, newY, newZ));
        }

        array->append(dataRow);
    }

    series->dataProxy()->resetArray(array);
    surface->addSeries(series);
    series->setProperty("EllipseId", m_ellipseCount);
    series->setProperty("Z", z);
    series->setProperty("Major", major);
    series->setProperty("Minor", minor);
    series->setProperty("Angle", angle);

    // 连接点击信号
    connect(series, &QSurface3DSeries::selectedPointChanged,
            this, [this](const QPoint &point) {
                if (point.x() >= 0 && point.y() >= 0) {
                    QSurface3DSeries *series = qobject_cast<QSurface3DSeries*>(sender());
                    onSeriesClicked(series);
                }
            });
}


void beamquality3d::clearAllEllipses()
{
    if (m_surface) {
        QList<QSurface3DSeries *> seriesList = m_surface->seriesList();
        for (QSurface3DSeries *series : seriesList) {
            m_surface->removeSeries(series);
            delete series;
        }
        m_ellipseCount = 0;
    }
}

void beamquality3d::removeEllipse(int ellipseId)
{
    if (m_surface) {
        QList<QSurface3DSeries *> seriesList = m_surface->seriesList();
        for (QSurface3DSeries *series : seriesList) {
            if (series->property("EllipseId").toInt() == ellipseId) {
                m_surface->removeSeries(series);
                delete series;
                break;
            }
        }
    }
}

void beamquality3d::on_addEllipseButton_clicked()
{
    float z = m_zValueSpinBox->value();
    float major = m_majorSpinBox->value();
    float minor = m_minorSpinBox->value();
    float angle = m_angleSpinBox->value();
    QColor color(QRandomGenerator::global()->bounded(256),
                 QRandomGenerator::global()->bounded(256),
                 QRandomGenerator::global()->bounded(256));
    addEllipseTo3DSurface(z, major, minor, angle, color);
}

void beamquality3d::on_clearButton_clicked()
{
    clearAllEllipses();
    m_selectedEllipseId = -1;
    m_removeButton->setEnabled(false);
}

void beamquality3d::onSeriesClicked(QSurface3DSeries *series)
{
    // 获取被点击的椭圆ID
    m_selectedEllipseId = series->property("EllipseId").toInt();

    // 更新UI显示当前选中椭圆的参数
    m_zValueSpinBox->setValue(series->property("Z").toDouble());
    m_majorSpinBox->setValue(series->property("Major").toDouble());
    m_minorSpinBox->setValue(series->property("Minor").toDouble());
    m_angleSpinBox->setValue(series->property("Angle").toDouble());

    // 启用删除按钮
    m_removeButton->setEnabled(true);
}

void beamquality3d::onLoadImageClicked()
{
    // 获取当前选中的椭圆系列
    QSurface3DSeries *series = m_surface->selectedSeries();
    if (!series) {
        QMessageBox::warning(this, tr("警告"), tr("请先选择一个椭圆"));
        return;
    }

    // 打开文件对话框选择图像
    QString fileName = QFileDialog::getOpenFileName(this,
        tr("打开图像"), "", tr("图像文件 (*.png *.jpg *.bmp)"));
    
    if (fileName.isEmpty()) return;
    
    // 加载图像
    QPixmap image(fileName);
    if (image.isNull()) {
        QMessageBox::warning(this, tr("错误"), tr("无法加载图像"));
        return;
    }
    
    // 填充椭圆
    fillEllipseWithImage(series, image);
}

void beamquality3d::fillEllipseWithImage(QSurface3DSeries *series, const QPixmap &image)
{
    // 检查输入有效性
    if (!series) {
        qWarning() << "Invalid series pointer";
        return;
    }

    if (image.isNull()) {
        qWarning() << "Invalid image";
        return;
    }


    QImage textureImage = image.toImage().convertToFormat(QImage::Format_RGB32);

    series->setTexture(textureImage);
    // 配置纹理显示方式
    series->setDrawMode(QSurface3DSeries::DrawSurface);
    series->setColorStyle(Q3DTheme::ColorStyleUniform);
    series->setFlatShadingEnabled(true); // 平面着色使纹理更清晰

}


void beamquality3d::on_removeButton_clicked()
{
    if (m_selectedEllipseId == -1) {
        return;
    }

    // 移除选中的椭圆
    removeEllipse(m_selectedEllipseId);
    m_selectedEllipseId = -1;
    m_removeButton->setEnabled(false);

    // 重置参数控件
    m_zValueSpinBox->setValue(0.0f);
    m_majorSpinBox->setValue(30.0f);
    m_minorSpinBox->setValue(20.0f);
    m_angleSpinBox->setValue(0.0f);
}